using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;
using trainstorm.InstanceClass.Obstacles;

namespace trainstorm.InstanceClass
{
	public class GameScreen : BaseClass.BaseScreen
	{
		private Player player;
		private List<Obstacle> obstacles;
		private Boss boss;
		private double lastBossDeath;
		private Random r;
		public string text;
		private const double bossTimeThreshold = 18;
		private Vector2 pos;
		private int counter = 0;

		public GameScreen() : base() {}
		public GameScreen(Game1 game1)
			: base(game1)
		{
			//this screen has 2 layers, background(panorama) and foreground(floor)
			layerVel = new Vector2[] { new Vector2(-50, 0), new Vector2(-200, 0) };
			layers = game.getInsManager().getGame().ToArray();
			layerPos = new Vector2[layers.Length];
			splitScreen = true;

			obstacles = new List<Obstacle>();
			player = new Player(game1);
			lastBossDeath = 0;
			r = new Random();
			pos = new Vector2(-1, -1);
			text = "";
		}

		public override void Update(Game1 game, GameTime gameTime)
		{
			text="";
			//if (!player.isDead())
			//{
				base.Update(game, gameTime);
				for (int i = 0; i < layers.Length; i++)
				{
					layerPos[i].X -= player.getVelX() * (float)gameTime.ElapsedGameTime.TotalSeconds;
					layerPos[i].X %= -(layers[i].Width);
				}
				//if (boss == null)
				//    lastBossDeath += gameTime.ElapsedGameTime.TotalSeconds;

				//TODO touch-touch thing
				TouchCollection touchLocations = TouchPanel.GetState();
				if (touchLocations.Count > 0)
				{
					TouchLocation touchLocation = touchLocations[0];

					if (touchLocation.State == TouchLocationState.Released)
						pos = new Vector2(-1);
					else if (boss != null)
					{
						if (new Rectangle((int)boss.getX(), (int)boss.getY(), boss.getSprite().Width, boss.getSprite().Height)
								.Contains((int)touchLocation.Position.X, (int)touchLocation.Position.Y))
							boss.drain();
						else
							boss.regenerate();
					}

					if (touchLocation.State == TouchLocationState.Moved
						&& !(boss == null ? false
							: new Rectangle((int)boss.getX(), (int)boss.getY(), boss.getSprite().Width, boss.getSprite().Height)
								.Contains((int)pos.X, (int)pos.Y)))
					{
						if (pos.X > -1 && pos.X < Game1.screenWidth + 1 
							&& pos.Y > -1 && pos.Y < Game1.screenHeight / 2 + 1)
						{
							if ((player.getHeadX() + touchLocation.Position.X - pos.X) < 0)
							{
								player.setHeadX(0);
							}
							else if ((player.getHeadX() + touchLocation.Position.X - pos.X) > 332)
							{
								player.setHeadX(332);
							}
							else
							{
								player.setHeadX(player.getHeadX() + touchLocation.Position.X - pos.X);
							}

							if ((player.getHeadY() + touchLocation.Position.Y - pos.Y) < 0)
							{
								player.setHeadY(0);
							}
							else if ((player.getHeadY() + touchLocation.Position.Y - pos.Y) > 380)
							{
								player.setHeadY(380);
							}
							else
							{
								player.setHeadY(player.getHeadY() + touchLocation.Position.Y - pos.Y);
							}
						}
						pos = touchLocation.Position;
					}

					while (TouchPanel.IsGestureAvailable)
					{
						GestureSample gesture = TouchPanel.ReadGesture();
						switch (gesture.GestureType)
						{
							case GestureType.Tap:
								text = "Tap";
								break;
						}
					}
				}

				//TODO obstacle randomizer
				//if (lastBossDeath > bossTimeThreshold && boss == null)
				//    boss = new Boss(game, 0);
				if (counter == 0)
				{
					int velX = r.Next(100) + 200;
					int posY = r.Next(200) + 75;
					int keluar = r.Next(4);
					if ((int)gameTime.TotalGameTime.TotalMilliseconds % 21 == 0)
					{
						if (keluar == 1)
						{
							counter = r.Next(3) + 2;
							int rn = r.Next(2);
							obstacles.Add(new Bush(game, new Vector2((Game1.screenWidth*2), posY)));
							for (int iter = 0; iter < counter; iter++)
							{
								int dum = obstacles.Count - 1;
								if (iter < 2)
								{
									obstacles.Add(new Bush(game, new Vector2
									((Game1.screenWidth * 2) + ((obstacles[dum].getSprite().Width * obstacles[dum].getScale() + 2) * (iter + 1)),
									 posY)));
								}
								else
								{
									if (rn == 0)
									{
										obstacles.Add(new Bush(game, new Vector2
										((Game1.screenWidth * 2) + ((obstacles[dum].getSprite().Width * obstacles[dum].getScale() + 2) * (iter + 1)),
										 posY - (obstacles[dum].getSprite().Height * obstacles[dum].getScale() + 2) )));
									}
									else
									{
										obstacles.Add(new Bush(game, new Vector2
										((Game1.screenWidth * 2) + ((obstacles[dum].getSprite().Width * obstacles[dum].getScale() + 2) * (iter + 1)),
										 posY + (obstacles[dum].getSprite().Height * obstacles[dum].getScale() + 2))));
									}
								}
							}
						}
						else if (keluar == 2)
						{
							counter = 1;
							obstacles.Add(new Totem(game, (Game1.screenWidth * 2), posY));
						}
						//else if (keluar != 1)
						//{
						//    obstacles.Add(new Frog(game, velX, new Vector2((Game1.screenWidth*2), posY)));
						//}
					}
				}
				else
				{
					if (Game1.screenWidth - obstacles[obstacles.Count - 1].getX()
						> (1.25 * obstacles[obstacles.Count - 1].getSprite().Width * obstacles[obstacles.Count - 1].getScale()))
					{
						counter = 0;
					}
				}

				if (boss != null)
					boss.Update(gameTime);
				player.Update(gameTime, game);
				int j = 0;
				while (j < obstacles.Count)
				{
					if (obstacles[j].getX() + (obstacles[j].getSprite().Width * obstacles[j].getScale()) < -5)
					{
						obstacles.RemoveAt(j);
					}
					else
					{
						obstacles[j].update(gameTime, layerVel[layerVel.Length - 1].X);
						//text = j.ToString() + " " + obstacles[j].pos.X.ToString() + " " + obstacles[j].pos.Y.ToString();
						j++;
						
					}
				}

				//check collision
				j = 0;
				bool nabrak = false;
				while ((j < obstacles.Count) && (!nabrak))
				{

					if (//kanan bawah
					   ((player.getHeadX() + player.getSprite().Width*0.3f > obstacles[j].getX()) &&
 					   (player.getHeadX() + player.getSprite().Width*0.3f < 
					   (obstacles[j].getX()+ obstacles[j].getSprite().Width*obstacles[j].getScale())) &&
					   (player.getHeadY() + player.getSprite().Height * 0.3f > obstacles[j].getY()) &&
					   (player.getHeadY() + player.getSprite().Height * 0.3f < 
					   (obstacles[j].getY() + obstacles[j].getSprite().Height * obstacles[j].getScale()))) ||
						//kanan atas
					   ((player.getHeadX() + player.getSprite().Width*0.3f > obstacles[j].getX()) &&
 					   (player.getHeadX() + player.getSprite().Width*0.3f < 
					   (obstacles[j].getX()+ obstacles[j].getSprite().Width*obstacles[j].getScale())) &&
					   (player.getHeadY() > obstacles[j].getY()) &&
					   (player.getHeadY() < 
					   (obstacles[j].getY() + obstacles[j].getSprite().Height * obstacles[j].getScale()))) ||
						//kiri bawah
					   ((player.getHeadX() > obstacles[j].getX()) &&
 					   (player.getHeadX() < 
					   (obstacles[j].getX()+ obstacles[j].getSprite().Width*obstacles[j].getScale())) &&
					   (player.getHeadY() + player.getSprite().Height * 0.3f > obstacles[j].getY()) &&
					   (player.getHeadY() + player.getSprite().Height * 0.3f < 
					   (obstacles[j].getY() + obstacles[j].getSprite().Height * obstacles[j].getScale()))) ||
						//kiri atas
					   ((player.getHeadX() > obstacles[j].getX()) &&
					   (player.getHeadX() <(obstacles[j].getX() + obstacles[j].getSprite().Width * obstacles[j].getScale())) &&
					   (player.getHeadY() > obstacles[j].getY()) &&
					   (player.getHeadY() <(obstacles[j].getY() + obstacles[j].getSprite().Height * obstacles[j].getScale()))) )
					{
						nabrak = true;
					}
					j++;
				}
				if (nabrak)
					text = "nabrak cui";


				//text += ((int)gameTime.TotalGameTime.TotalMilliseconds/100).ToString();
			//}
			//else //Game Over
			//{
			//    game.setScreen(new MenuScreen(game));
			//}
		}
		public override void Draw(SpriteBatch batch)
		{
			base.Draw(batch);
			if (boss != null)
				boss.Draw(batch);
			foreach (Obstacle obs in obstacles)
				obs.Draw(batch);
			player.Draw(batch);
			batch.DrawString(game.font, text, new Vector2(10, 10), Color.Tomato);
			
		}
	}
}
